home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 4 / CU Amiga Magazine's Super CD-ROM 04 (1996)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1996-11].iso / magazine / psion / new / opp16f.lzx / manual2.txt < prev    next >
Text File  |  1996-09-20  |  35KB  |  859 lines

  1. 8. INCLUDE FILES
  2.  
  3. Other OPP files may be included into the file being translated using
  4. the #include directive. This takes one of two forms as shown in the
  5. following examples:
  6.  
  7.         #include <os\calls>
  8.         #include "my_procs.oph"
  9.         
  10. The first #include will cause the pre-processor to search for a file
  11. in the following locations:
  12.  
  13.         M:\OPP\INCLUDE\OS\CALLS.OPH
  14.         A:\OPP\INCLUDE\OS\CALLS.OPH
  15.         B:\OPP\INCLUDE\OS\CALLS.OPH
  16.         
  17. Or in the case of the MSDOS version the file will be searched for in
  18. the directory...
  19.  
  20.        C:\OPP\INCLUDE\
  21.        
  22. ...unless the -I option is used on the OPP command line, e.g.
  23.  
  24.        OPP -iD:\PSION\OPP\INCLUDE TEST.OPP
  25.        
  26. If the file is found it will be included into the translation at that
  27. point. This form of include is used for system include files. These
  28. include files are generic files which are not written for any one
  29. specific OPP program.
  30.  
  31. Note that by default the OPH extension is assumed for system include
  32. files, although this may be overridden by explicitly stating the
  33. extension in the include filename.
  34.  
  35. The second form of include, which uses the delimiters "" rather than
  36. <>, is for specifying include files which are specific to the program
  37. being translated. The processor will default to looking in the same
  38. directory as the program being translated and will look for a file
  39. with the same extension. A full filename which includes a path and
  40. file extension may be given to override this.
  41.  
  42. Usually include files only contain pre-processor directives such as
  43. macro definitions, in which case the file extension OPH should be
  44. used rather than OPP. The OPH editor is supplied to allow include
  45. files to be listed on the system screen separate from any OPP and OPL
  46. files.
  47.  
  48. 8.1 System include files
  49. ------------------------
  50. A large number of system include files are supplied with OPP with
  51. lots of useful pre-defined macro definitions. There are macro
  52. definitions for the operating system calls available in the Psion
  53. ROM, macros used with Psion's OOP methods, symbolic macros used with
  54. various OPL commands and various other useful macros. For example:
  55.  
  56. Macro name                  Purpose
  57.  
  58. ESC                         Represents escape character, 27
  59. P_FUPDATE                   Used with the OPL command ioopen()
  60. FilExecute                  OS call number
  61. SPRINTF(buf,format,args)    Uses OS call along lines of C sprintf()
  62.  
  63. Origin and organisation of include files
  64. ----------------------------------------
  65. Starting from version 1.5F of OPP the system include files used with
  66. OPP are based on the system include files supplied with the Psion C
  67. SDK. These files were originally copyright Psion and are supplied
  68. with kind permission from Psion. The OPP versions of the include
  69. files contain exactly the same macros and structures which are
  70. defined in the SDK include files. The OPP include files also have
  71. similarly names to the C SDK include files. However with OPP the
  72. include files are organised slightly differently. The OPP files are
  73. split into a number of directories (in the SDK all are located in a
  74. single directory) as follows:
  75.  
  76. Directory                           Contents
  77.  
  78. \OPP\INCLUDE\LIB\                   OPP library files. See section 10.3
  79.                                     for details.
  80. \OPP\INCLUDE\OO\                    OOP defines. These are used when
  81.                                     making use of Psion's Object
  82.                                     Oriented Programming technique. The
  83.                                     files include category handles and
  84.                                     method numbers. In the SDK these
  85.                                     defines are mixed with the other
  86.                                     files, I have split them out to
  87.                                     reduce the memory requirements for
  88.                                     the files.
  89. \OPP\INCLUDE\OPP\                   OPP specific additions. These are
  90.                                     my own includes with some useful
  91.                                     OPL specific definitions.
  92. \OPP\INCLUDE\OS\                    These include files contain defines
  93.                                     used when accessing the OS
  94.                                     functions available in the Psion
  95.                                     ROM. Function and sub-function
  96.                                     numbers are defined.
  97. \OPP\INCLUDE\P\                     These are based entirely on the SDK
  98.                                     p_* includes. Note that the leading
  99.                                     p_ has been stripped off and that
  100.                                     any OOP defines removed and placed
  101.                                     in the OO directory includes to
  102.                                     save memory.
  103. \OPP\INCLUDE\SDK\                   The remaining SDK includes.
  104.  
  105. OO include files
  106. ----------------
  107. The include files within the OO directory contain definitions used
  108. with the object oriented libraries in the Psion ROM, i.e. category
  109. and method numbers. To use these files you need to be familiar with
  110. the Object Oriented Programming (OOP) techniques used with the Psion.
  111. The Psion SDK contains detailed information on using OOP. There is
  112. one publicly available source of information on using OOP techniques,
  113. this is in the form of a Microsoft Word file which contains an early
  114. copy of one of the manuals from the SDK. This manual discusses
  115. programming using the HWIM library which is built into the Psion ROM.
  116. Most Psion archive sites contain this file as the archive
  117. OODOC201.ZIP.
  118.  
  119. OPP include files
  120. -----------------
  121. The files in the OPP directory contain macros used with general OPL
  122. commands:
  123.  
  124. Include file  Usage
  125.  
  126. debug.oph     debug macros for tracing code
  127. dialog.oph    macros used with OPL dialogue boxes
  128. envars.oph    environment variables
  129. graphics.oph  macros used with OPL graphics functions
  130. hw.oph        defines S3t if OPP used on Series 3, S3a is used on a
  131.               Series 3a
  132. keys.oph      key code definitions, e.g. #define ESC 27
  133. limits.oph    Psion datatype limits, e.g. #define INT_MAX 32767
  134. misc.oph      various macros, e.g. #define TRUE -1
  135. opa.oph       used when building OPA's, e.g. #define OPA_3AICON $1000
  136. process.oph   used when accessing a processes low memory addresses
  137.  
  138. OS include files
  139. ----------------
  140. There are a large number of useful operating system functions
  141. available in the Psion ROM that may called from OPL. The OPL commands
  142. CALL and OS provide access to these functions. When using these
  143. commands you need to know the function and sub-function numbers of
  144. the function you are calling. For example, there is a function called
  145. FilExecute, which allows you to start another application from OPL,
  146. this function is identified by function number $87 and sub-function
  147. $01. OS calls are grouped by function number, so file related
  148. functions have the same $87 function number.
  149.  
  150. The include files with the OS\ prefix contain OS call function and
  151. sub-function numbers and OS call macros. These are grouped by
  152. function number, so the file related functions are in OS\FIL.OPH.
  153. Rather than writing code using the numbers $87 and $01, you should
  154. make use of the #defines for these numbers in order to make the code
  155. more readable. So in the case of the FilExecute function the
  156. following two #defines, which are declared in OS\FIL.OPH, should be
  157. used:
  158.  
  159.         #define FilManager $87
  160.         #define FilExecute $0100
  161.         
  162. The best source of information on how to use Psion OS calls, defines
  163. or programming for Psion in general is the software development kit
  164. (SDK) available from Psion. There is also a publicly available source
  165. of information on the Psion operating system calls. The "" include
  166. many details about the OS calls in the Psion ROM as well as file
  167. formats used by the internal applications. These files are available
  168. from the usual archives of Psion software (Imperial College archive,
  169. Frontiernet, CompuServe, CIX, 3Lib,...). Refer to these files for
  170. further information on how to use the operating system calls.
  171.  
  172. The file OS\CALLS.OPH contains some useful macros to use when making
  173. OS calls. For example, to determine the locale of the Psion being
  174. used (English, German, French,...) there is the GenGetLangauge OS
  175. call. To use this call without OPP you would write code as follows:
  176.  
  177.         PROC getlang:
  178.                 local axreg%,bxreg%,cxreg%,dxreg%,sireg%,direg%,osflags%
  179.                 axreg%=$1B00
  180.                 osflags%=OS($8B,addr(axreg%))
  181.                 PRINT axreg%
  182.         ENDP
  183.         
  184. The following shows how the OS\CALL.OPH and OS\GEN.OPH files can be
  185. used with OPP to do the same thing:
  186.  
  187.         #include <os\call>
  188.         #include <os\gen>
  189.         PROC getlang:
  190.                 local OSREGS
  191.                 OSSUB(GenManager,GenGetLanguageCode)
  192.                 PRINT AX
  193.         ENDP
  194.         
  195. Refer to the comments within the OS\CALL.OPH file for further details
  196. on how to use the OSSUB() and OSFN() macros.
  197.  
  198. Other system include files
  199. --------------------------
  200. The files in the P and SDK directories are based on the include files
  201. from the Psion C SDK. For information on these include files refer to
  202. the SDK documentation.
  203.  
  204. 8.2 OPP_INIT.OPH
  205. ----------------
  206. Whenever OPP translates a file it will automatically include the
  207. following file before reading any OPP code:
  208.  
  209.         OPP_INIT.OPH
  210.         
  211. With the Psion version of OPP this file should be in the \OPP\INCLUDE
  212. directory on any drive. With the MSDOS version of OPP this file
  213. should be on the C: driver or in the directory specified with the -i
  214. command line option.
  215.  
  216. If there are any OPP directives which are used in all OPP code then
  217. the OPP_INIT.OPH file is a good place to put them without having to
  218. explicitly use a #include <opp_init>.
  219.  
  220. 8.3 Building large applications using #include
  221. ----------------------------------------------
  222. The source code limits imposed by the MSDOS based OPL translators
  223. mean that the following technique is restricted to the Psion based
  224. version of OPP only.
  225.  
  226. Using the #include directive it is possible to build large programs
  227. where the total size of the OPP source code exceeds the 40K limit
  228. imposed by the Psion based program editor.
  229.  
  230. Take the real example of the project planning application for the
  231. Psion 3a called  - plugging another shareware program I have written
  232. :-). This currently consists of three main OPP source files
  233. (PLAN.OPP, PLAN1.OPP and PLAN2.OPP), all of which are around 35K in
  234. size. One way to handle this is to use the LOADM OPL command to load
  235. PLAN1.OPO and PLAN2.OPO modules from the main PLAN.OPA module.
  236. However using the pre-processor one single large file could be
  237. created by translating a three line file containing the following:
  238.  
  239.         #include "PLAN.OPP"
  240.         #include "PLAN1.OPP"
  241.         #include "PLAN2.OPP"
  242.         
  243. The advantages of this approach are as follows:
  244.  
  245.    -  the resultant one file is easier to distribute and install than
  246.       three separate files,
  247.       
  248.    -  it saves a small amount of code required to find and load the
  249.       separate modules and check the versions are compatible,
  250.       
  251.    -  it saves up to 40K of RAM during translation since only the one
  252.       three line source file is resident in the Program editor during
  253.       translation. This can be useful if you are short of RAM when
  254.       translating.
  255.  
  256. 9. PRAGMAS
  257.  
  258. The #pragma directive controls a number of features of the OPL pre-
  259. processor. The following options are available:
  260.  
  261.        #pragma no_revtran
  262.        #pragma stop_on [warn|error|never]
  263.        #pragma show_input [on|off]*
  264.        #pragma show_output [on|off]*
  265.        #pragma show_macros*
  266.        #pragma show_procs*
  267.        #pragma check_procs*
  268.        #pragma to_file filename
  269.        #pragma pause*
  270.        #pragma font size**
  271.        #pragma pack size
  272.        #pragma debug [on|off]
  273.        #pragma translator [s3atran|s3tran|watran|hctran]***
  274.        
  275. * These pragma's are disabled when using the MSDOS version of OPP
  276. with ODE. This is because these pragma pause output and request a key
  277. to be pressed. User input is not possible when using ODE since OPP is
  278. called behind the scenes. The thing which controls the disabling of
  279. this pragma is the definition of an ODE macro, i.e.
  280.  
  281.        #define ODE
  282.        
  283. The recommended way to define the ODE macro is when configuring the
  284. ODE.INI file, (see setting of Trandef option in installation
  285. section).
  286.  
  287. ** The font pragma is not available with the MSDOS version of OPP.
  288.  
  289. *** The translator pragma is only available with the MSDOS version of
  290. OPP.
  291.  
  292. 9.1 No_revtran
  293. ---------------
  294. Revtran is a program which allows OPO files to be reverse translated
  295. back into OPL source code. The no_revtran pragma may be used to
  296. prevent the reverse translation of the no_revtran line. The way it
  297. works is to insert some OPL code into the translation which causes
  298. the Revtran program to fall over.
  299.  
  300. Note that I cannot guarantee that the no_revtran option will stop
  301. future versions of Revtran from working, or that it will keep
  302. sufficiently determined people from reverse translating your
  303. programs. The no_revtran option has been tested against Revtran 3.3a.
  304.  
  305. The "#pragma no_revtran" line should appear within a procedure at the
  306. top of the OPP file. Revtran will be able to reverse translate up to
  307. this line but no further.
  308.  
  309. 9.2 Stop_on
  310. -----------
  311. Use "#pragma stop_on never" to instruct the pre-processor to display
  312. any pre-processor error or warning messages and to continue
  313. processing the OPP code. Use "#pragma stop_on error" to stop whenever
  314. an error occurs but continue if there is a warning. "#pragma stop_on
  315. warn" will cause the pre-processor to stop on both warnings and
  316. errors. The default mode is "error", in which case as soon as a pre-
  317. processor error is detected control will return to the OPP editor.
  318.  
  319. The "never" switch could be used whenever you want to find all errors
  320. within a newly written include file in one go, rather than fixing
  321. each one individually. It may also be useful if any error occurs
  322. within an include file and you need to pinpoint exactly which line
  323. the error was on.
  324.  
  325. 9.3 Show_input
  326. --------------
  327. Use "#pragma show_input on" (the on part is optional) to instruct the
  328. pre-processor to display lines as they are read from the program
  329. editor from that point onwards. Use #pragma show_input off to switch
  330. the display off.
  331.  
  332. Do not use this pragma when using OPP with ODE.
  333.  
  334. 9.4 Show_output
  335. ---------------
  336. Use "#pragma show_output on" (the on is optional) to instruct the pre-
  337. processor to display lines as they are sent to the OPL translator,
  338. i.e. after pre-processing. Use #pragma show_output off to switch
  339. output off.
  340.  
  341. Do not use this pragma when using OPP with ODE.
  342.  
  343. 9.5 Show_macros
  344. ---------------
  345. "#pragma show_macros" will instruct the pre-processor to print out
  346. all defined macros at that point in the translation.
  347.  
  348. Do not use this pragma when using OPP with ODE.
  349.  
  350. 9.6 Show_procs
  351. --------------
  352. When this pragma is encountered OPP will print out the name of each
  353. procedure as it is defined. This is useful if you want to see the
  354. progress of the translation and which procedures have been included.
  355. Do not use this pragma when using OPP with ODE.
  356.  
  357. 9.7 Check_procs
  358. ---------------
  359. When OPP processes OPL source it records the procedures which have
  360. been defined and those which have been called. The check_procs pragma
  361. instructs OPP to check the list of procedures called against the list
  362. of defined procedures. If OPP finds any procedures which have been
  363. called but not defined then it will list them. OPP will also list any
  364. procedures which are defined but never explicitly called. Note that
  365. in this later case OPP cannot detect procedure calls which are made
  366. using a string variable (refer to the Psion Programming Manual,
  367. Advanced Topics section). The best place for this pragma is at the
  368. end of the OPL source.
  369.  
  370. Do not use this pragma when using OPP with ODE.
  371.  
  372. 9.8 To_file
  373. -----------
  374. "#pragma to_file preproc.opl" would instruct the pre-processor to
  375. send pre-processed lines both to the translator and the file
  376. preproc.opl. This may be used to extract pre-processor directives and
  377. macros from an OPP source file. Note that the filename does not
  378. include quotes.
  379.  
  380. 9.9 Pause
  381. ---------
  382. "#pragma pause" will pause the pre-processor until a key is pressed.
  383. This could be used at the end of the OPP source file or immediately
  384. after a show_macros pragma.
  385.  
  386. Do not use this pragma when using OPP with ODE.
  387.  
  388. 9.10 Font
  389. ---------
  390. "#pragma font 1" will set the font used by OPP to the font with id 1.
  391. The number specifies the font id which should be in the range 1 to 13
  392. inclusive. Refer to the OPL Programming Manual for a list of font
  393. types and associated font id's. Although this pragma may appear
  394. anywhere within an OPP file the best place for it is in the
  395. OPP_INIT.OPH file mentioned in section 8.
  396.  
  397. Do not use this pragma when using the MSDOS version of OPP.
  398.  
  399. 9.11 Pack
  400. ---------
  401. The use of this pragma statement is strongly discouraged. If you
  402. think you may need to use it then contact me for a full explanation.
  403.  
  404. "#pragma pack 2" will set the structure packing size to 2 bytes. The
  405. packing size controls how OPP packs fields into structures and the
  406. alignment of fields within a structure. The default pack size is 1
  407. which means that OPP packs structures so that there are no spaces
  408. between fields.
  409.  
  410. 9.12 Debug
  411. ----------
  412. This pragma statement instructs OPP to add in-line debug statements
  413. to the translated program. This is for use with a run-time source
  414. level debugger called OPPDBG. OPPDBG is available separately as a
  415. complimentary utility to OPP. OPPDBG allows you to debug a running
  416. OPL program as follows:
  417.  
  418.    -  View each source line as it executes.
  419.    -  Single step through each line or step over entire procedures.
  420.    -  Set breakpoints so that the program stops at given lines.
  421.    -  View and set local variables by name in the running program.
  422.    -  View and set any memory location in the programs data segment.
  423.  
  424. To use OPPDBG you need to add the following line as the very first
  425. line in the source file:
  426.  
  427.         #pragma debug
  428.  
  429. At the bottom of the source include the file OPPDBG.OPH, i.e. use the
  430. line:
  431.  
  432.         #include <OPPDBG>
  433.         
  434. This assumes OPPDBG.OPH has been installed into the OPP system
  435. include directory \OPP\INCLUDE\.
  436.  
  437. When you start the OPL program it will automatically start up the
  438. debugger and allow you to debug the program.
  439.  
  440. Do not use this pragma if you do not have OPPDBG installed or use the
  441. statement for a program which is to be distributed as a finished
  442. application.
  443.  
  444. Refer to the user manual with OPPDBG for further details.
  445.  
  446. 9.13 Translator
  447. ---------------
  448. This pragma directive controls which translator is used with the
  449. MSDOS version of OPP. By default OPP will call S3ATRAN to create the
  450. resultant OPO or OPA file. To use an alternative translator such as
  451. S3TRAN, WATRAN or HCTRAN use this pragma, e.g.
  452.  
  453.        #pragma translator s3tran
  454.        #pragma translator watran
  455.        #pragma translator hctran
  456.  
  457. 10. LANGUAGE EXTENSIONS
  458.  
  459. OPP provides a number of extensions to the OPL language. These
  460. facilities are in addition to the normal pre-processor directives
  461. discussed in the preceding sections.
  462.  
  463. 10.1 Multi-dimensional arrays
  464. -----------------------------
  465. With standard OPL only one dimensional arrays are supported, for
  466. example:
  467.  
  468.         local a%(5)        /* 1-d array of integers */
  469.         local a$(5,8)      /* 1-d array of 5x8 character strings */
  470.         a%(1)=1
  471.         a%(2)=2
  472.         a$(1)="abcdefgh"
  473.         
  474. When using OPP multi-dimensional arrays may be used, for example:
  475.  
  476.         local a%(5,3)      /* 2-d array of integers */
  477.         local a$(2,5,8)    /* 2-d array of 8 character strings */
  478.         a%(1,1)=1
  479.         a%(1,2)=2
  480.         a$(1,1)="abcdefgh"
  481.         
  482. OPP supports arrays with up to 20 dimensions!
  483.  
  484. The memory structure for a multi-dimensional array is such that the
  485. if you add one to the last subscript then this will be located in
  486. memory adjacent to the previous array element, for example a%(2,3) is
  487. stored as:
  488.  
  489.         a%(1,1)  a%(1,2)  a%(1,3)  a%(2,1)  a%(2,2)  a%(2,3)
  490.         
  491. Multi-dimensional arrays may be declared as local or global
  492. variables. However in the case of global variables an additional
  493. syntax is required in order to be able to access any variables which
  494. are outside the scope of the current OPL file. Suppose for example
  495. you have the following in one OPL module or source file:
  496.  
  497.         global        a%, b%(2,3)
  498.         
  499. In a separate OPL module which may be loaded into memory using the
  500. standard LOADM OPL function you can reference the global variables
  501. from the first module:
  502.  
  503.         a%=1
  504.         b%(2,1)=2
  505.         
  506. In the case of the variable a% there is no problem with the above
  507. code, however in the case of the 2d array b%() OPP needs to know what
  508. the definition of the array was in order to work out where the
  509. element (2,1) is in memory. This is accomplished using an external
  510. variable definition:
  511.  
  512.         extern        b%(2,3)
  513.         
  514. The extern declaration syntax behaves exactly like a local or global
  515. OPL definition but is used merely to declare to OPP the dimensions of
  516. global multi-dimension arrays which are outside the scope of the
  517. current file.
  518.  
  519. 10.2 Structures
  520. ---------------
  521. This section describes OPP support for standard C style structures
  522. and pointers. Casual and incorrect use of some of the techniques
  523. described here could cause anything from a program crash or even a
  524. soft reset and data loss. You have been warned!
  525.  
  526. The following sample code shows how structures are declared and used:
  527.  
  528.         STRUCT user_data
  529.                 id%
  530.                 forename$(40)
  531.                 surname$(40)
  532.                 char_data#
  533.                 int_data%
  534.                 long_data&
  535.                 float_data
  536.                 string_data$(50)
  537.         ENDS
  538.         PROC main:
  539.                 local <user_data*>p%
  540.                 p% = make%:
  541.                 show(p%)
  542.                 destroy:(p%)
  543.         ENDP
  544.         PROC make%:
  545.                 local <user_data*>ptr%
  546.                 ptr%=alloc(SIZEOF(user_data))
  547.                 if ptr%=0
  548.                         stop
  549.                 endif
  550.                 ptr%->id%=1
  551.                 ptr%->forename$="Andy"
  552.                 ptr%->surname$="Clarkson"
  553.                 ptr%->char_data#=%a
  554.                 ptr%->int_data%=1
  555.                 ptr%->long_data&=123
  556.                 ptr%->float_data=1.23
  557.                 ptr%->string_data$="Some data"
  558.                 return ptr%
  559.         ENDP
  560.         PROC show:(<user_data*>ptr%)
  561.                 print ptr%->id%
  562.                 print ptr%->forename$
  563.                 print ptr%->surname$
  564.                 print ptr%->char_data#
  565.                 print ptr%->int_data%
  566.                 print ptr%->long_data&
  567.                 print ptr%->float_data
  568.                 print ptr%->string_data$
  569.         ENDP
  570.         PROC destroy%:(<user_data*>ptr%)
  571.                 freealloc ptr%
  572.         ENDP
  573.         
  574. A structure is used to access a block of memory. The structure
  575. defines a number of fields which represent locations within the block
  576. of memory into which data may be written and from which may be read.
  577.  
  578. The STRUCT line starts a structure definition and names the
  579. structure. The structure name is used later when defining pointers or
  580. variables which point to a location in memory which contains data in
  581. the given format. The structure name must be unique amongst all
  582. structure definitions.
  583.  
  584. The structure and field names may contain any characters used in a
  585. normal OPL variable plus the underscore character. Unlike OPL
  586. variables the names may be of any length.
  587.  
  588. The STRUCT line is followed by the names of the fields within the
  589. structure, with one line per field. These field names are used when
  590. referencing the memory within a structure. The ENDS line marks the
  591. end of the structure.
  592.  
  593. Like standard OPL variables the last character of a field name
  594. defines the type of the field and the amount of memory the field
  595. represents. The standard int (%), long (&), float (no special
  596. terminator) and string ($) types are supported as field types. An
  597. additional field type is also supported by OPP which is marked by a
  598. terminating # character. This type occupies a single byte in memory
  599. and can hold a value in the range 0 to 255.
  600.  
  601. A field may also be declared as a 1-dimensional array using the
  602. normal bracket notation (note: multi-dimensional arrays are not
  603. supported in structure field definitions).
  604.  
  605. The STRUCT/ENDS definition does not generate any code, it simply
  606. tells OPP about the size and shape of a structure. To use a structure
  607. you must declare a pointer to a structure of the given type and then
  608. allocate some memory of the correct size.
  609.  
  610. Any global, local, extern or procedure variable may be declared as a
  611. pointer to a structure of a named type by preceding the variable with
  612. the structure name within angle brackets. A "*" character should
  613. follow the structure name to indicate the variable is a pointer to a
  614. structure (note for C programmers: pointers to structures are
  615. supported at this release, not structure variables). An integer
  616. variable should be used for structure pointers, i.e. ptr% not ptr&,
  617. ptr or ptr$.
  618.  
  619. An N-dimensional array of pointers may be declared as well as a
  620. single pointer, e.g. the following declares an array of 10 pointers
  621. to 10 separate structures:
  622.  
  623.         local <user_data*>ptrs%(10)
  624.         
  625. Once a structure pointer variable has been declared some memory of
  626. the correct size should be allocated to hold the data and the pointer
  627. set to the start of the block of memory. e.g.
  628.  
  629.         ptr%=alloc(SIZEOF(user_data))
  630.         ptrs%(1)=alloc(SIZEOF(user_data))
  631.         
  632. SIZEOF() is a built-in macro which gives the size of a named
  633. structure. This is required when allocating memory, as shown above.
  634. The memory should freed when it is no-longer required, e.g.
  635.  
  636.         freealloc ptr%
  637.         freealloc ptrs%(1)
  638.         
  639. To assign a value to a field within the allocated structure use the
  640. pointer variable name and the field name separated by the "->"
  641. notation, e.g. ptr%->id%=1
  642.  
  643. Be particularly careful when assigning values to string fields and
  644. field arrays, consider:
  645.  
  646.         STRUCT a_struct
  647.                 name$(4)
  648.                 array%(2)
  649.         ENDS
  650.         etc...
  651.         ptr%->name$="12345"
  652.         ptr%->array%(3)=1
  653.         
  654. Both of the above would write data outside the memory for the fields
  655. and cause corruption of data. These types of errors will not be
  656. trapped by the OPL interpreter when the program runs.
  657.  
  658. To read a field value use the same "->" notation, e.g.
  659.  
  660.         if (ptr%->id%>1)
  661.         
  662. There is one other built in OPP macro which is used with structures.
  663. OFFSETOF(struct,field) will give the offset of the field called
  664. "field" within the structure called "struct". So for example
  665. OFFSETOF(user_data, int_data%) gives 85 since the int_data% field is
  666. offset 85 bytes into the user_data structure. The OFFSETOF() macro is
  667. typically used when you need to access the memory address of a given
  668. field directly, e.g. you could write:
  669.  
  670.         peekw uadd(ptr%,OFFSETOF(user_data,int_data%))
  671.         
  672. ...which would be equivalent to...
  673.  
  674.         ptr%->int_data%
  675.         
  676. C programmers who are familiar with C style structures should note
  677. the following restrictions in OPP at this release:
  678.  
  679.    -  Nested structures are not supported.
  680.    
  681.    -  If you want to include a field within a structure which is a
  682.       pointer to another structure, use a standard OPL integer variable
  683.       such as ptr%, not the <user_data*>ptr% notation.
  684.       
  685.    -  When defining a string field of size N within a structure the
  686.       actual space it occupies is N+1 since the first byte is used to store
  687.       the length of the string. Such a string can store up to and including
  688.       N characters.
  689.       
  690.    -  The C style operators such as ++ which are discussed later are
  691.       not supported with structure fields.
  692.       
  693. 10.3 Procedure libraries
  694. ------------------------
  695. OPP supports a special type of procedure which is designed to enable
  696. procedure source libraries to be built. A library procedure is
  697. defined using LIBPROC rather than PROC, e.g.:
  698.  
  699.         LIBPROC test:
  700.                 print "test"
  701.         ENDP
  702.         
  703. A library procedure is identical to a normal procedure with one
  704. exception. When OPP processes an OPL source file it records which
  705. procedures have been called. When OPP finds a library procedure it
  706. checks the list of procedures which have been used and only includes
  707. the procedure if it has been called.
  708.  
  709. The library procedure allows a number of useful procedures to be
  710. grouped into a single OPL source file and then the file included as a
  711. whole in a number of separate programs. Only the procedures actually
  712. used within a program will be translated and included in the final
  713. OPO or OPA module.
  714.  
  715. Note that OPP processes source serially so that if a LIBPROC appears
  716. in the source code but is not referenced until later in the file then
  717. it will not be included.
  718.  
  719. Sample procedure libraries
  720. --------------------------
  721. To demonstrate the use of procedure libraries there are some sample
  722. files supplied with OPP in the \INCLUDE\LIB\ directory which
  723. demonstrate the following:
  724.  
  725.    -  How to use the standard Psion print engine from OPL (providing
  726.       a print and print preview facility). Refer to the comments in the
  727.       printlib.opp file for details. To see the code in action translate
  728.       and run the following:
  729.       
  730.           #include <lib\printlib.oph>
  731.           PROC main:
  732.               ptest:
  733.           ENDP
  734.           #include <lib\printlib.opp>
  735.           #include <lib\util_lib.opp>
  736.           
  737.    -  Various utility procedures, handling C<->OPL string
  738.       conversions, copying blocks of memory,.
  739.  
  740. 10.4 'C' style operators
  741. ------------------------
  742. OPP provides a number of facilities which are normally found in C
  743. code.
  744.  
  745. The OPL pre-processor will look for the characters '|' and '0x'
  746. within the OPP code and will convert them into something which the
  747. OPL translator will recognise. This feature is provided for greater
  748. compatibility with standard C include files.
  749.  
  750. The '|' character (entered into the OPP editor using the key
  751. combination CTRL-124) is used in C code, and is equivalent to the bit-
  752. wise OR operator in OPL, i.e. the following line...
  753.  
  754.         #define        FLAG        (&1 | &4 | &32)
  755.         
  756. ...is equivalent to...
  757.  
  758.         #define        FLAG        (&1 OR &4 OR &32)
  759.         
  760. Note that when using bit-wise operations which make use of the
  761. OPPEVAL() macro or in #if statements it is vital that the values are
  762. explicitly forced to integer values by preceding them with & or $. If
  763. this is not done then it can result in a logical OR operation rather
  764. than a bit-wise OR, consider:
  765.  
  766.         OPPEVAL(1 | 2)
  767.         OPPEVAL(&1 | &2)
  768.         
  769. The first will use a logical OR since 1 and 2 are treated as floating
  770. point numbers and will give a result of -1, whereas the second will
  771. use a bit-wise OR and give the result 3. Logical and bit-wise OR's
  772. are discussed at the back of the Psion Programming Manual.
  773.  
  774. OPL uses the $ and & characters as prefixes for short and long
  775. hexadecimal numbers respectively. In 'C' 0x is used as the prefix.
  776. For convenience the pre-processor will convert any 0x to $ or &, so
  777. the following line...
  778.  
  779.         #define        FLAGS        (0x100|0x00000400)
  780.         
  781. ...is equivalent to...
  782.  
  783.         #define        FLAGS        ($100 OR &00000400)
  784.         
  785. If there are more than 4 digits following the 0x characters a long
  786. hexadecimal will be generated (using the & prefix), otherwise a short
  787. will be used (using the $ prefix).
  788.  
  789. A number of other C style operators which are found in normal C code
  790. are also supported by OPP:
  791.  
  792.    Operator                  Purpose              Example
  793.       ++         set variable=variable+1          i%++
  794.       --         set variable=variable-1          i%--
  795.       +=         set variable=variable+value      i%+=2
  796.       -=         set variable=variable-value      i%-=2
  797.       *=         set variable=variable*value      i%*=2
  798.       /=         set variable=variable/value      i%/=2
  799.  
  800. 11. HISTORY
  801.  
  802. 16 May 95   V1.0B           First beta release
  803.  
  804. 7 June 95   V1.0F           First release
  805.  
  806. 25 Aug 95   V1.1B           Beta release
  807.  
  808. 6 Sep 95    V1.1F           Second release.
  809.                             Multi-dimensional arrays.
  810.                             LIBPROCs added.
  811.                             Option to check for undefined procedures.
  812.                             show_procs pragma.
  813.                             New C style operators .
  814.                             OPPEVAL() macro.
  815.                             __PROC__ macro.
  816.                             Bug fix for use of comma as decimal
  817.                             character.
  818.                             no_revtran updated to defeat Revtran 3.3a.
  819.                             
  820. 3 Dec 95    V1.2B           Beta release.
  821.  
  822. 17 Jan 96   V1.2F           Third release.
  823.                             Added structure definitions.
  824.                             Added structure pointers.
  825.                             #elif now supported.
  826.                             Added #pragma font size.
  827.                             Added #pragma pack size.
  828.                             Line continuation character support.
  829.                             Anti-revtran mechanism made much more
  830.                             robust.
  831.                             Some additions to system include files
  832.                             #pragma check_procs also reports procedures
  833.                             not called.
  834.                             A few minor bug-fixes.
  835.                             
  836. 25 Feb 96   V1.3F           Added hooks for run-time debugger (OPPDBG).
  837.                             Couple of minor bug-fixes.
  838.                             
  839. 9 Mar 96    V1.4F           Now uses additional lines available when
  840.                             using S3a emulator.
  841.                             Couple of minor bug-fixes for debugger and
  842.                             multi-dimensional arrays.
  843.                             
  844. 17 Aug 96   V1.5B           Beta release.
  845.  
  846. 10 Sep 96   V1.5F           Added MSDOS version of OPP.
  847.                             Psion C SDK based system include files.
  848.                             Much smaller and faster.
  849.  
  850. 14 Sep 96   V1.6F        Bug fix release
  851.  
  852.  
  853. 12. FURTHER DEVELOPMENT
  854.  
  855. If you have any comments, suggestions or find any bugs then let me
  856. know. Also if you write any useful include files or expand upon any
  857. of the system include files it would be worth considering having them
  858. added to a future version of OPP.
  859.